package com.yoofn.framework.activity

import android.content.Intent
import android.databinding.DataBindingUtil
import android.databinding.ViewDataBinding
import android.os.Bundle
import android.support.annotation.AnimRes
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.app.AppCompatActivity
import android.view.LayoutInflater
import android.widget.Toast
import com.yoofn.framework.Global
import com.yoofn.framework.R
import com.yoofn.framework.config.ViewConfig
import com.yoofn.framework.http.HttpNetData
import com.yoofn.framework.http.IHttpFramework


/**
 *
 * Created by kalshen on 17/6/2.
 * @描述 activity的基类
 */
abstract class BaseActivity<D : ViewDataBinding> : AppCompatActivity(), IHttpFramework {
    /**
     * 具有dataBinding 数据绑定特性的 contentView
     * 可以直接调用被layout 包裹的 控件资源id
     * 例:content.textView.text="hello"
     * 不懂的 自己去dataBinding
     */
    lateinit var contentView: D


    /**
     * activity的配置对象
     */
    val viewConfig by lazy {
        setupConfig()
    }

    val swipeRefresh by lazy {
        SwipeRefreshLayout(this).takeIf { viewConfig.shouldSwipeRefresh }
    }


    //activity 的初始化
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //设置状态栏颜色
        //fixme 状态栏颜色
//        BarUtils.setColor(this, resources.getColor(R.color.colorPrimary))
        //启用databinding
        contentView = DataBindingUtil.inflate<D>(LayoutInflater.from(this), viewConfig.layoutId, swipeRefresh, false)
        //初始化下拉刷新
        initSwipeRefresh()

        setContentView(swipeRefresh ?: contentView.root)
        //初始化业务逻辑
        doInteractive()
    }

    private fun initSwipeRefresh() {
        swipeRefresh?.addView(contentView.root)
        swipeRefresh?.setOnRefreshListener {
            viewConfig.httpNetData.let {
                if (it.isEmpty()) closeRefresh()
                else addRequest(*viewConfig.httpNetData)
            }
        }
    }


    /**
     * 设置activity的配置信息
     * @return 返回activity 的配置对象
     */
    abstract fun setupConfig(): ViewConfig

    /**
     * 处理控件的交互
     */
    private fun doInteractive() {
        //初始化view
        initView()
        //初始化点击事件
        initClick()
    }

    /**
     * 初始化界面
     */
    abstract fun initView()

    /**
     * 初始化点击事件
     */
    abstract fun initClick()

    override fun onRequestStart(what: Int) {
        swipeRefresh?.isRefreshing = true
    }

    override fun onRequestFinished(what: Int, unFinishedNetData: List<HttpNetData?>) {
        if (unFinishedNetData.isEmpty()) closeRefresh()
    }

    private fun closeRefresh() {
        swipeRefresh?.postDelayed({ swipeRefresh?.isRefreshing = false }, 1000)
    }


    /**
     * 物理返回按钮的事件拦截action
     */
    private var backPressedAction: (() -> Boolean)? = null

    /**
     * 是否一直要拦截返回事件
     */
    private var isAlwaysIntercept = false

    /**
     * 设置物理返回键事件将覆盖原本的返回键事件
     * action 返回true 则表示拦截 false 表示不拦截
     * @param backPressedAction 默认物理返回按钮的拦截事件
     * @param isAlwaysIntercept 是否一直处于拦截状态.
     * true：每一次返回键的回调都会执行action;false：action 调用完则销毁(只会调用一次)
     */
    fun setCustomBackPressedAction(backPressedAction: (() -> Boolean), isAlwaysIntercept: Boolean = false) {
        this.backPressedAction = backPressedAction
        this.isAlwaysIntercept = isAlwaysIntercept
    }


    override fun onBackPressed() {
        //判断是否被拦截
        if (customInterceptBackPressed()) return
        //框架默认的返回事件
        defaultBackPressed()
    }

    /**
     * 用户自定义的返回拦截事件
     */
    private fun customInterceptBackPressed(): Boolean {
        if (backPressedAction?.invoke() ?: false) {
            //是否一直拦截
            if (isAlwaysIntercept) {
                return true
            } else {
                backPressedAction = { false }
            }
        }
        return false
    }

    /**
     * 物理返回键的 校对初始时间
     */
    var time: Long = 0L
    private var exitAction: (() -> Unit)? = null

    /**
     * 默认物理返回键的事件
     */
    private fun defaultBackPressed() {
        val currentTimeMillis = System.currentTimeMillis()
        if (supportFragmentManager.backStackEntryCount == 0) {
            //如果当前activity 不是 root activity 执行默认返回操作
            if (currentTimeMillis - time < Global.BaseActivityConfig.DOUBLE_PRESSED_TIME_INTERVAL || Global.BaseActivityConfig.ROOT_ACTIVITY_NAME != this::class.simpleName) {
                finish()
                if (Global.BaseActivityConfig.ROOT_ACTIVITY_NAME == this::class.simpleName) {
                    overridePendingTransition(appExitAnim[0], appExitAnim[1])
                } else {
                    overridePendingTransition(pageBackAnim[0], pageBackAnim[1])
                }
            } else {
                time = System.currentTimeMillis()
                //如果用户自定义了退出操作 则执行用户的
                val exitAction1 = exitAction
                if (exitAction1 == null) {
                    Toast.makeText(this, Global.BaseActivityConfig.DOUBLE_PRESSED_MESSAGE, Toast.LENGTH_SHORT).show()
                } else {
                    exitAction1.invoke()
                }
            }
        } else {
            supportFragmentManager.popBackStack()
        }
    }

    /**
     * @param exitAction 用户自定义退出程序的action
     */
    fun setCustomExitAction(exitAction: () -> Unit) {
        this.exitAction = exitAction
    }

    /**
     * 设置 页面 返回动画
     * 前一个页面进入的动画
     * 当前页面返回的动画
     * 默认:左进右出
     */
    private val pageBackAnim = intArrayOf(R.anim.in_from_left, R.anim.out_to_right)

    /**
     * 设置 页面 返回动画
     * @param enterAnim 前一个页面进入的动画
     * @param exitAnim 当前页面返回的动画
     */
    fun setPageBackAnim(@AnimRes enterAnim: Int, @AnimRes exitAnim: Int) {
        pageBackAnim[0] = enterAnim
        pageBackAnim[1] = exitAnim
    }

    /**
     * app 退出的动画
     * 第一个是 桌面 launch 进入的动画
     * 第二个是 本 app 退出的动画
     * 默认:渐变
     */
    private val appExitAnim = intArrayOf(R.anim.fade_in, R.anim.fade_main_out)

    /**
     * 设置 app 退出动画
     * @param enterAnim 桌面 launch 进入的动画
     * @param exitAnim 本 app 退出的动画
     */
    fun setAppExitAnim(@AnimRes enterAnim: Int, @AnimRes exitAnim: Int) {
        appExitAnim[0] = enterAnim
        appExitAnim[1] = exitAnim
    }




}
